package com.example.test.conview.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextPaint;
import android.widget.FrameLayout;

import com.puty.conputyutils.LeoUtils;
import com.puty.conputyutils.LogUtils;
import com.puty.conputyview.R;
import com.puty.conputyview.common.PutyConst;
import com.puty.conputyview.interfaces.DragElementCallBack;
import com.puty.conputyview.interfaces.OnUnSelected;
import com.puty.conputyview.utils.ToastUtils;
import com.puty.conputyview.view.core.BaseElement;
import com.puty.conputyview.view.core.Element;
import com.puty.conputyview.view.core.Label;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 单个元素公有基类模板
 */
public abstract class BaseDrag extends FrameLayout {

    private final static String TAG = "BaseDrag";

    /**
     * 每次移动的距离
     */
    private final static int TRAVEL_DISTANCE = 1;

    /**
     * 当前操作 1 移动 2 缩放  4 双击  5 删除
     */
    protected int ACTION = PutyConst.ACTION_TOUCH_DEFAULT;

    /**
     * Bitmap 对象
     */
    public Bitmap mBufferBitmap;

    /**
     * 画布对象
     */
    protected Canvas mCanvas;

    /**
     * 元素模板   宽
     */
    protected int width;
    /**
     * 元素模板    高
     */
    protected int height;

    /**
     * 元素变更状态回调对象
     */
    private DragElementCallBack dragElementCallBack;

    /**
     * 清空选中状态回调对象
     */
    private OnUnSelected onUnSelected;

    /**
     * // 当前标签
     */
    public Label lb;

    public Bitmap currentLabelImage = null;

    /**
     * 当前操作的元素
     */
    public BaseElement currentElement;

    /**
     * 点击点
     */
    protected PointF point;

    public BaseDrag(Context context, int width, int height) {
        super(context);
        setWillNotDraw(false);
        if (width < 1) {
            width = 1;
        }
        if (height < 1) {
            height = 1;
        }
        this.width = width;
        this.height = height;
        mBufferBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        LogUtils.i(TAG, "width = " + width + " ， height = " + height);
        lb = new Label("", 100, 100);
        mCanvas = new Canvas();
        point = new PointF();
        if (mBufferBitmap != null && !mBufferBitmap.isRecycled()) {
            mCanvas.setBitmap(mBufferBitmap);
        }
    }

    /**
     * 元素改变通知
     *
     * @param element
     */
    public void elementChangeNoitcs(BaseElement element) {
        if (dragElementCallBack == null) {
            LogUtils.i(TAG, "dragElementCallBack = null");
            return;
        }
        //未被选中且未被锁定的元素
        if (element != null && element.isselected) {
            dragElementCallBack.onElementAttributeUpdate(element.entityId);
        } else {
            //取消所有元素选中
            setUnSelected();
            dragElementCallBack.onClearElement();
        }
    }

    /**
     * 根据打印预览返回状态设置选中元素
     *
     * @return 返回设置选中元素
     */
    protected BaseElement setSelectede() {
        BaseElement selectEL = null;
        for (BaseElement el : lb.Elements) {
            if (el.backselected) {
                el.isselected = true;
                selectEL = el;
            }
        }
        for (BaseElement el : lb.Elements) {
            el.backselected = false;
        }
        return selectEL;
    }

    /**
     * 取消所有元素选中
     */
    public void setUnSelected() {
        for (BaseElement el : lb.Elements) {
            el.isselected = false;
            el.iszoom = false;
        }
        if (onUnSelected == null) {
            LogUtils.i(TAG, "onUnSelected = null");
            return;
        }
        onUnSelected.onUnSelected();
    }

    /**
     * 获取缩放元素
     */
    /**
     * 获取缩放元素
     *
     * @param xShaft x轴坐标
     * @param yShaft y轴坐标
     * @return 缩放元素对象
     */
    protected BaseElement getScale(float xShaft, float yShaft) {
        for (int i = lb.Elements.size() - 1; i >= 0; i--) {
            BaseElement element = ((Element)lb.Elements.get(i)).isscale(xShaft, yShaft);
            if (element != null) {
                return element;
            }
        }
        return null;
    }

    /**
     *  获取删除元素
     *
     * @param xShaft  x轴坐标
     * @param yShaft  y轴坐标
     * @return 删除元素对象
     */
    protected BaseElement getDelete(float xShaft, float yShaft) {
        for (BaseElement el : lb.Elements) {
            BaseElement element = ((Element)el).isDelete(xShaft, yShaft);
            if (element != null) {
                return el;
            }
        }
        return null;
    }

    /**
     * 获取选中的元素
     *
     * @param xShaft  x轴坐标
     * @param yShaft  y轴坐标
     * @return 选中的元素对象
     */
    protected BaseElement getSelected(float xShaft, float yShaft) {
        ArrayList<BaseElement> elementList = new ArrayList<>();
        BaseElement returnElement = null;
        for (int i = lb.Elements.size() - 1; i >= 0; i--) {
            BaseElement el = lb.Elements.get(i);
            if (el.left <= xShaft && (el.left + el.width) >= xShaft && el.top <= yShaft && (el
                    .top + el.height) >= yShaft) {
                elementList.add(el);
            }
        }
        if (elementList.size() > 0) {
            returnElement = elementList.get(0);
            for (int i = 0; i < elementList.size(); i++) {
                if (returnElement.width * returnElement.height > elementList.get(i)
                        .width * elementList.get(i).height) {
                    returnElement = elementList.get(i);
                }
            }
        }
        return returnElement;
    }

    /**
     * 设置元素变更状态回调对象
     *
     * @param dragElementCallBack 回调对象
     */
    public void setDragElementCallBack(DragElementCallBack dragElementCallBack) {
        this.dragElementCallBack = dragElementCallBack;
    }

    /**
     * 设置清空选中状态回调对象
     *
     * @param onUnSelected 回调对象
     */
    public void setOnUnSelected(OnUnSelected onUnSelected) {
        this.onUnSelected = onUnSelected;
    }

    /**
     * 删除选中的元素,并且返回
     *
     * @return 返回未被选中的元素
     */
    public BaseElement deleteSelected() {
        BaseElement select = null;
        List<BaseElement> baseElementList = new CopyOnWriteArrayList<>();
        for (BaseElement el : lb.Elements) {
            // 未选中或者已锁定的元素
            if (!el.isselected || el.isLock == 1) {
                baseElementList.add(el);
            }
        }
        // 未选中或者已锁定的元素是否还有
        if (baseElementList.size() > 0) {
            //默认第一个选中
            baseElementList.get(0).isselected = true;
            select = baseElementList.get(0);
        }
        //替换最新的元素对象
        this.lb.Elements = baseElementList;
        return select;
    }

    /**
     * 计算选中元素的个数
     *
     * @return 选中元素的总数
     */
    public int getSelectedElementSize() {
        int num = 0;
        if (lb == null || lb.Elements == null) {
            LogUtils.i(TAG, "getSelectedElementSize ---> lb == null or lb.Elements == null , num == " + num);
            return num;
        }
        for (BaseElement el : lb.Elements) {
            if (el.isselected) {
                num++;
            }
        }
        return num;
    }

    /**
     * 元素对齐方向
     *
     * @param pos 对齐方向
     */
    public void alignViews(int pos) {
        if (getSelectedElementSize() < 1) {
            ToastUtils.showToast(LeoUtils.getApplication()
                    .getString(R.string.element_select_the_element_first));
            LogUtils.i(TAG, "alignViews ---> 没有选中要移动的元素");
            return;
        }
        int padding = 8;
        List<BaseElement> list = new ArrayList<>();
        BaseElement element = null;
        switch (pos) {
            case PutyConst.ALIGN_HORIZONTAL_CENTERING: // 水平居中
                if (getSelectedElementSize() > 1) {
                    //水平中分布
                    list.clear();
                    element = null;
                    for (BaseElement el : lb.Elements) {
                        // 未被选中跳过
                        if (!el.isselected) {
                            continue;
                        }
                        // 被锁定的跳过
                        if (el.isLock == 1) {
                            continue;
                        }
                        //选出一个宽度最大的
                        if (element == null || element.width < el.width) {
                            element = el;
                        }
                        list.add(el);
                    }
                    //检查选中的元素是否不少于2个
                    if (list.size() < 2 || element == null) {
                        break;
                    }
                    for (BaseElement el : list) {
                        el.left = element.left + element.width / 2 - el.width / 2;
                    }
                } else {//水平居中
                    for (BaseElement el : lb.Elements) {
                        if (!el.isselected) {
                            continue;
                        }
                        if (el.isLock == 1) {
                            continue;
                        }
                        el.left = (width - el.width) / 2;
                    }
                }
                break;
            case PutyConst.ALIGN_LEFT_ALIGN: // 左对齐
                if (getSelectedElementSize() > 1) {//水平左分布
                    list = new ArrayList<>();
                    element = null;
                    for (BaseElement el : lb.Elements) {
                        if (!el.isselected) {
                            continue;
                        }
                        if (el.isLock == 1) {
                            continue;
                        }
                        if (element == null || element.left > el.left) {//选出最左边的元素
                            element = el;
                        }
                        list.add(el);
                    }
                    //检查选中的元素是否不少于2个
                    if (list.size() < 2 || element == null) {
                        break;
                    }
                    for (BaseElement el : list) {
                        el.left = element.left;
                    }
                } else {//左对齐
                    for (BaseElement el : lb.Elements) {
                        if (!el.isselected) {
                            continue;
                        }
                        if (el.isLock == 1) {
                            continue;
                        }
                        el.left = padding;
                    }
                }
                break;
            case PutyConst.ALIGN_RIGHT_ALIGN: // 右对齐
                if (getSelectedElementSize() > 1) {//水平右分布
                    list = new ArrayList<>();
                    element = null;
                    for (BaseElement el : lb.Elements) {
                        if (!el.isselected) {
                            continue;
                        }
                        if (el.isLock == 1) {
                            continue;
                        }
                        //选出最右边的元素
                        if (element == null || element.left + element.width < el.left + el.width) {
                            element = el;
                        }
                        list.add(el);
                    }
                    //检查选中的元素是否不少于2个
                    if (list.size() < 2 || element == null) {
                        break;
                    }
                    for (BaseElement el : list) {
                        el.left = element.left + element.width - el.width;
                    }
                } else {//右对齐
                    for (BaseElement el : lb.Elements) {
                        if (!el.isselected) {
                            continue;
                        }
                        if (el.isLock == 1) {
                            continue;
                        }
                        el.left = width - el.width - padding;
                    }
                }
                break;
            case PutyConst.ALIGN_VERTICAL_CENTERING: // 垂直居中
                if (getSelectedElementSize() > 1) {//垂直中分布
                    list = new ArrayList<>();
                    element = null;
                    for (BaseElement el : lb.Elements) {
                        if (!el.isselected) {
                            continue;
                        }
                        if (el.isLock == 1) {
                            continue;
                        }
                        //选出最右边的元素
                        if (element == null || element.height < el.height) {
                            element = el;
                        }
                        list.add(el);
                    }
                    //检查选中的元素是否不少于2个
                    if (list.size() < 2 || element == null) {
                        break;
                    }
                    for (BaseElement el : list) {
                        el.top = element.top + element.height / 2 - el.height / 2;
                    }
                } else {//垂直居中
                    for (BaseElement el : lb.Elements) {
                        if (!el.isselected) {
                            continue;
                        }
                        if (el.isLock == 1) {
                            continue;
                        }
                        el.top = (height - el.height) / 2;
                    }
                }
                break;
            case PutyConst.ALIGN_TOP_ALIGNMENT: // 上对齐
                if (getSelectedElementSize() > 1) {//垂直顶分布
                    for (BaseElement el : lb.Elements) {
                        if (!el.isselected) {
                            continue;
                        }
                        if (el.isLock == 1) {
                            continue;
                        }
                        if (element == null || element.top > el.top) {//选出最上面的元素
                            element = el;
                        }
                        list.add(el);
                    }
                    //检查选中的元素是否不少于2个
                    if (list.size() < 2 || element == null) {
                        break;
                    }
                    for (BaseElement el : list) {
                        el.top = element.top;
                    }
                } else {//上对齐
                    for (BaseElement el : lb.Elements) {
                        if (!el.isselected) {
                            continue;
                        }
                        if (el.isLock == 1) {
                            continue;
                        }
                        el.top = padding;
                    }
                }
                break;
            case PutyConst.ALIGN_BOTTOM_ALIGNMENT: // 下对齐
                if (getSelectedElementSize() > 1) {//垂直底分布
                    list = new ArrayList<>();
                    element = null;
                    for (BaseElement el : lb.Elements) {
                        if (!el.isselected) {
                            continue;
                        }
                        if (el.isLock == 1) {
                            continue;
                        }
                        //选出最下面的元素
                        if (element == null || element.top + element.height < el.top + el.height) {
                            element = el;
                        }
                        list.add(el);
                    }
                    //检查选中的元素是否不少于2个
                    if (list.size() < 2 || element == null) {
                        break;
                    }
                    for (BaseElement el : list) {
                        el.top = element.top + element.height - el.height;
                    }
                } else {//下对齐
                    for (BaseElement el : lb.Elements) {
                        if (!el.isselected) {
                            continue;
                        }
                        if (el.isLock == 1) {
                            continue;
                        }
                        el.top = height - el.height - padding;
                    }
                }
                break;
            case PutyConst.ALIGN_HORIZONTAL_EQUIPARTITION: // 水平均分
                list.clear();
                for (BaseElement el : lb.Elements) {
                    if (!el.isselected) {
                        continue;
                    }
                    if (el.isLock == 1) {
                        continue;
                    }
                    list.add(el);
                }
                //检查选中的元素是否不少于3个
                if (list.size() < 3) {
                    break;
                }
                float elementWidthNum = 0;
                for (BaseElement el : list) {
                    elementWidthNum += el.width;
                }
                //元素排序
                for (int i = 0; i < list.size() - 1; i++) {
                    for (int j = i + 1; j < list.size(); j++) {
                        if (list.get(i).left > list.get(j).left) {
                            BaseElement element1 = list.get(i);
                            list.set(i, list.get(j));
                            list.set(j, element1);
                        }
                    }
                }
                BaseElement leftmostElement = list.get(0);//最左边的那个元素
                BaseElement rightmostElement = list.get(list.size() - 1);//最右边的那个元素

                elementWidthNum = elementWidthNum - rightmostElement.width;
//                计算剩下的间隙大小
                float gap = rightmostElement.left - leftmostElement.left - elementWidthNum;

                if (gap > 0) {
                    float singleGap = gap / (list.size() - 1);
                    for (int i = 1; i < list.size(); i++) {
                        BaseElement element1 = list.get(i);
                        float left = 0;
                        for (int j = 0; j < i; j++) {
                            if (j == 0) {
                                left = list.get(0).left + list.get(0).width + singleGap;
                            } else {
                                left = left + list.get(j).width + singleGap;
                            }
                        }
                        element1.left = left;
                    }
                } else {
                    ToastUtils.showToast(LeoUtils.getApplication()
                            .getString(R.string.element_width_and_greater_than_label_width));
                }
                break;
            case PutyConst.ALIGN_VERTICAL_EQUIPARTITION: // 垂直均分
                list = new ArrayList<>();
                for (BaseElement el : lb.Elements) {
                    if (!el.isselected) {
                        continue;
                    }
                    if (el.isLock == 1) {
                        continue;
                    }
                    list.add(el);
                }
                //检查选中的元素是否不少于3个
                if (list.size() < 3) {
                    break;
                }
                float elementHeightNum = 0;
                for (BaseElement el : list) {
                    elementHeightNum += el.height;
                }
                //元素排序
                for (int i = 0; i < list.size() - 1; i++) {
                    for (int j = i + 1; j < list.size(); j++) {
                        if (list.get(i).top > list.get(j).top) {
                            BaseElement element1 = list.get(i);
                            list.set(i, list.get(j));
                            list.set(j, element1);
                        }
                    }
                }
                BaseElement onTopElement = list.get(0);//最左边的那个元素
                BaseElement lowestElement = list.get(list.size() - 1);//最右边的那个元素

                elementHeightNum = elementHeightNum - lowestElement.height;
//                计算剩下的间隙大小
                gap = lowestElement.top - onTopElement.top - elementHeightNum;

                if (gap > 0) {
                    float singleGap = gap / (list.size() - 1);
                    for (int i = 1; i < list.size(); i++) {
                        BaseElement element1 = list.get(i);
                        float top = 0;
                        for (int j = 0; j < i; j++) {
                            if (j == 0) {
                                top = list.get(0).top + list.get(0).height + singleGap;
                            } else {
                                top = top + list.get(j).height + singleGap;
                            }
                        }
                        element1.top = top;
                    }
                } else {
                    ToastUtils.showToast(LeoUtils.getApplication()
                            .getString(R.string.element_height_and_greater_than_gap_height));
                }
                break;
            case PutyConst.ALIGN_MOVE_UP: // 往上移动
                for (BaseElement el : lb.Elements) {
                    if (!el.isselected) {
                        continue;
                    }
                    if (el.isLock == 1) {
                        continue;
                    }
                    el.top += TRAVEL_DISTANCE;
                }
                break;
            case PutyConst.ALIGN_MOVE_BOTTOM: // 往下移动
                for (BaseElement el : lb.Elements) {
                    if (!el.isselected) {
                        continue;
                    }
                    if (el.isLock == 1) {
                        continue;
                    }
                    el.top -= TRAVEL_DISTANCE;
                }
                break;
            case PutyConst.ALIGN_MOVE_LEFT: // 往左移动
                for (BaseElement el : lb.Elements) {
                    if (!el.isselected) {
                        continue;
                    }
                    if (el.isLock == 1) {
                        continue;
                    }
                    el.left -= TRAVEL_DISTANCE;
                }
                break;
            case PutyConst.ALIGN_MOVE_RIGHT: // 往右移动
                for (BaseElement el : lb.Elements) {
                    if (!el.isselected) {
                        continue;
                    }
                    if (el.isLock == 1) {
                        continue;
                    }
                    el.left += TRAVEL_DISTANCE;
                }
                break;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 清空画布
        mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        mCanvas.drawColor(Color.parseColor("#ffefefef"));
        if (currentLabelImage != null) {
            int wideBackground = currentLabelImage.getWidth();
            int highBackground = currentLabelImage.getHeight();
            if (lb.mirrorLabelType == 1) {//上下镜像
                highBackground /= 2;
            } else if (lb.mirrorLabelType == 2) {//左右镜像
                wideBackground /= 2;
            }

            Rect s = new Rect(0, 0, wideBackground, highBackground);
            RectF d = new RectF(0, 0, width, height);
            mCanvas.drawBitmap(currentLabelImage, s, d, null);
        } else {
            TextPaint paint = new TextPaint();
            paint.setAntiAlias(true);
            paint.setColor(Color.WHITE);
            // 设置样式-空心矩形
            paint.setStyle(Paint.Style.FILL);
            mCanvas.drawRoundRect(new RectF(0, 0, width, height), 20, 20, paint);
        }
    }
}
